<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>围棋游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #f5f5dc;
            padding: 20px;
        }
        .header {
            margin-bottom: 20px;
            text-align: center;
        }
        .controls {
            display: flex;
            justify-content: space-between;
            width: 500px;
            margin-bottom: 20px;
        }
        .info-panel {
            display: flex;
            justify-content: space-between;
            width: 500px;
            margin-bottom: 10px;
        }
        .board {
            position: relative;
            width: 500px;
            height: 500px;
            background-color: #dcb35c;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
        }
        .grid {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
        .vertical-line, .horizontal-line {
            position: absolute;
            background-color: #000;
        }
        .vertical-line {
            width: 1px;
            height: 100%;
        }
        .horizontal-line {
            width: 100%;
            height: 1px;
        }
        .star-point {
            position: absolute;
            width: 8px;
            height: 8px;
            background-color: #000;
            border-radius: 50%;
            transform: translate(-4px, -4px);
        }
        .stone {
            position: absolute;
            width: 24px;
            height: 24px;
            border-radius: 50%;
            transform: translate(-12px, -12px);
            box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4);
        }
        .black {
            background: radial-gradient(circle at 30% 30%, #444, #000);
        }
        .white {
            background: radial-gradient(circle at 30% 30%, #fff, #ddd);
        }
        .coordinates {
            position: absolute;
            font-size: 12px;
            color: #000;
        }
        .message {
            margin-top: 15px;
            font-weight: bold;
            height: 20px;
        }
        button {
            padding: 8px 16px;
            cursor: pointer;
            background-color: #4a6ea9;
            color: white;
            border: none;
            border-radius: 4px;
        }
        button:hover {
            background-color: #3a5b8c;
        }
        select {
            padding: 8px;
        }
        .captured {
            padding: 5px 10px;
            background-color: rgba(255, 255, 255, 0.7);
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>围棋游戏</h1>
    </div>
    
    <div class="controls">
        <select id="gameMode">
            <option value="player">双人模式</option>
            <option value="ai">人机模式</option>
        </select>
        <select id="boardSize">
            <option value="9">9×9</option>
            <option value="13">13×13</option>
            <option value="19" selected>19×19</option>
        </select>
        <button id="restartButton">重新开始</button>
        <button id="passButton">虚手</button>
        <button id="resignButton">认输</button>
    </div>

    <div class="info-panel">
        <div id="blackCaptured" class="captured">黑方提子: 0</div>
        <div id="turnInfo">轮到: 黑方</div>
        <div id="whiteCaptured" class="captured">白方提子: 0</div>
    </div>

    <div class="board" id="board"></div>
    <div class="message" id="message"></div>

    <script>
        // 游戏状态
        const gameState = {
            mode: 'player', // 'player' 或 'ai'
            size: 19,
            board: [],
            turn: 'black', // 'black' 或 'white'
            lastMove: null,
            history: [],
            koPoint: null,
            blackCaptured: 0,
            whiteCaptured: 0,
            gameOver: false,
            passes: 0
        };
        
        // 初始化游戏
        function initGame() {
            gameState.size = parseInt(document.getElementById('boardSize').value);
            gameState.mode = document.getElementById('gameMode').value;
            gameState.board = Array(gameState.size).fill().map(() => Array(gameState.size).fill(null));
            gameState.turn = 'black';
            gameState.lastMove = null;
            gameState.history = [];
            gameState.koPoint = null;
            gameState.blackCaptured = 0;
            gameState.whiteCaptured = 0;
            gameState.gameOver = false;
            gameState.passes = 0;
            
            updateCapturedDisplay();
            drawBoard();
            updateMessage("");
        }
        
        // 绘制棋盘
        function drawBoard() {
            const board = document.getElementById('board');
            // 清空棋盘
            board.innerHTML = '';
            
            // 创建网格
            const grid = document.createElement('div');
            grid.className = 'grid';
            board.appendChild(grid);
            
            const cellSize = 500 / (gameState.size + 1);
            
            // 绘制横线和纵线
            for (let i = 0; i < gameState.size; i++) {
                const verticalLine = document.createElement('div');
                verticalLine.className = 'vertical-line';
                verticalLine.style.left = `${cellSize * (i + 1)}px`;
                grid.appendChild(verticalLine);
                
                const horizontalLine = document.createElement('div');
                horizontalLine.className = 'horizontal-line';
                horizontalLine.style.top = `${cellSize * (i + 1)}px`;
                grid.appendChild(horizontalLine);
                
                // 绘制坐标
                const letterCoord = document.createElement('div');
                letterCoord.className = 'coordinates';
                letterCoord.textContent = String.fromCharCode(65 + (i >= 8 ? i + 1 : i)); // 跳过字母I
                letterCoord.style.top = '2px';
                letterCoord.style.left = `${cellSize * (i + 1)}px`;
                grid.appendChild(letterCoord);
                
                const numberCoord = document.createElement('div');
                numberCoord.className = 'coordinates';
                numberCoord.textContent = gameState.size - i;
                numberCoord.style.left = '2px';
                numberCoord.style.top = `${cellSize * (i + 1) - 6}px`;
                grid.appendChild(numberCoord);
            }
            
            // 绘制星位
            const starPoints = [];
            if (gameState.size === 19) {
                starPoints.push([3, 3], [3, 9], [3, 15], [9, 3], [9, 9], [9, 15], [15, 3], [15, 9], [15, 15]);
            } else if (gameState.size === 13) {
                starPoints.push([3, 3], [3, 9], [6, 6], [9, 3], [9, 9]);
            } else if (gameState.size === 9) {
                starPoints.push([2, 2], [2, 6], [4, 4], [6, 2], [6, 6]);
            }
            
            starPoints.forEach(([x, y]) => {
                const star = document.createElement('div');
                star.className = 'star-point';
                star.style.left = `${cellSize * (x + 1)}px`;
                star.style.top = `${cellSize * (y + 1)}px`;
                grid.appendChild(star);
            });
            
            // 绘制棋子
            for (let y = 0; y < gameState.size; y++) {
                for (let x = 0; x < gameState.size; x++) {
                    if (gameState.board[y][x]) {
                        const stone = document.createElement('div');
                        stone.className = `stone ${gameState.board[y][x]}`;
                        stone.style.left = `${cellSize * (x + 1)}px`;
                        stone.style.top = `${cellSize * (y + 1)}px`;
                        
                        // 标记最后一手棋
                        if (gameState.lastMove && gameState.lastMove.x === x && gameState.lastMove.y === y) {
                            stone.style.boxShadow = gameState.board[y][x] === 'black' ? 
                                '0 0 0 2px white' : '0 0 0 2px black';
                        }
                        
                        board.appendChild(stone);
                    }
                }
            }
            
            // 添加点击事件
            board.onclick = handleBoardClick;
            
            // 更新轮次信息
            document.getElementById('turnInfo').textContent = `轮到: ${gameState.turn === 'black' ? '黑方' : '白方'}`;
        }
        
        // 处理棋盘点击
        function handleBoardClick(e) {
            if (gameState.gameOver) {
                return;
            }
            
            // 如果是AI模式且是AI的回合，不接受点击
            if (gameState.mode === 'ai' && gameState.turn === 'white') {
                return;
            }
            
            const rect = e.target.getBoundingClientRect();
            const boardRect = document.getElementById('board').getBoundingClientRect();
            const x = e.clientX - boardRect.left;
            const y = e.clientY - boardRect.top;
            
            const cellSize = 500 / (gameState.size + 1);
            const gridX = Math.round(x / cellSize) - 1;
            const gridY = Math.round(y / cellSize) - 1;
            
            // 检查是否在棋盘范围内
            if (gridX < 0 || gridX >= gameState.size || gridY < 0 || gridY >= gameState.size) {
                return;
            }
            
            // 尝试落子
            if (placeStone(gridX, gridY)) {
                // 如果是AI模式，让AI落子
                if (gameState.mode === 'ai' && gameState.turn === 'white' && !gameState.gameOver) {
                    setTimeout(aiMove, 500);
                }
            }
        }
        
        // 落子逻辑
        function placeStone(x, y) {
            // 如果位置已经有棋子，不能落子
            if (gameState.board[y][x] !== null) {
                return false;
            }
            
            // 检查打劫点
            if (gameState.koPoint && gameState.koPoint.x === x && gameState.koPoint.y === y) {
                updateMessage("不能在打劫点落子");
                return false;
            }
            
            // 复制棋盘状态用于测试
            const testBoard = gameState.board.map(row => [...row]);
            testBoard[y][x] = gameState.turn;
            
            // 检查是否有提子
            const capturedStones = findCapturedStones(testBoard, gameState.turn === 'black' ? 'white' : 'black');
            
            // 检查自杀手
            if (capturedStones.length === 0) {
                const selfCaptured = isSelfCaptured(testBoard, x, y, gameState.turn);
                if (selfCaptured) {
                    updateMessage("不能下自杀手");
                    return false;
                }
            }
            
            // 通过所有检查，可以落子
            gameState.board[y][x] = gameState.turn;
            gameState.passes = 0;
            
            // 更新最后一手棋
            gameState.lastMove = {x, y};
            
            // 保存历史
            gameState.history.push({
                board: gameState.board.map(row => [...row]),
                turn: gameState.turn,
                lastMove: {...gameState.lastMove},
                blackCaptured: gameState.blackCaptured,
                whiteCaptured: gameState.whiteCaptured
            });
            
            // 提子
            const captured = removeCaptures();
            
            // 检查打劫
            gameState.koPoint = null;
            if (captured.length === 1 && isKoSituation(x, y, captured[0])) {
                gameState.koPoint = captured[0];
            }
            
            // 切换回合
            gameState.turn = gameState.turn === 'black' ? 'white' : 'black';
            
            // 更新显示
            drawBoard();
            updateCapturedDisplay();
            updateMessage("");
            
            return true;
        }
        
        // 检查自杀手
        function isSelfCaptured(board, x, y, color) {
            const group = findConnectedStones(board, x, y);
            return !hasLiberties(board, group);
        }
        
        // 查找连接的棋子
        function findConnectedStones(board, x, y) {
            const color = board[y][x];
            if (!color) return [];
            
            const visited = Array(gameState.size).fill().map(() => Array(gameState.size).fill(false));
            const connected = [];
            
            function dfs(x, y) {
                if (x < 0 || x >= gameState.size || y < 0 || y >= gameState.size || visited[y][x] || board[y][x] !== color) {
                    return;
                }
                
                visited[y][x] = true;
                connected.push({x, y});
                
                dfs(x + 1, y);
                dfs(x - 1, y);
                dfs(x, y + 1);
                dfs(x, y - 1);
            }
            
            dfs(x, y);
            return connected;
        }
        
        // 检查是否有气
        function hasLiberties(board, group) {
            for (const {x, y} of group) {
                // 检查四个方向
                const directions = [{dx: 1, dy: 0}, {dx: -1, dy: 0}, {dx: 0, dy: 1}, {dx: 0, dy: -1}];
                
                for (const {dx, dy} of directions) {
                    const nx = x + dx;
                    const ny = y + dy;
                    
                    if (nx >= 0 && nx < gameState.size && ny >= 0 && ny < gameState.size && board[ny][nx] === null) {
                        return true;
                    }
                }
            }
            return false;
        }
        
        // 找出被提掉的棋子
        function findCapturedStones(board, color) {
            const captured = [];
            
            for (let y = 0; y < gameState.size; y++) {
                for (let x = 0; x < gameState.size; x++) {
                    if (board[y][x] === color) {
                        const group = findConnectedStones(board, x, y);
                        if (!hasLiberties(board, group)) {
                            captured.push(...group);
                        }
                    }
                }
            }
            
            return captured;
        }
        
        // 移除被提掉的棋子
        function removeCaptures() {
            const opponent = gameState.turn === 'black' ? 'white' : 'black';
            const captured = findCapturedStones(gameState.board, opponent);
            
            for (const {x, y} of captured) {
                gameState.board[y][x] = null;
            }
            
            if (gameState.turn === 'black') {
                gameState.blackCaptured += captured.length;
            } else {
                gameState.whiteCaptured += captured.length;
            }
            
            return captured;
        }
        
        // 检查打劫情况
        function isKoSituation(x, y, captured) {
            // 检查是否符合打劫条件：刚好提了一个子，且周围只有一个空位
            const directions = [{dx: 1, dy: 0}, {dx: -1, dy: 0}, {dx: 0, dy: 1}, {dx: 0, dy: -1}];
            let emptyCount = 0;
            
            for (const {dx, dy} of directions) {
                const nx = x + dx;
                const ny = y + dy;
                
                if (nx >= 0 && nx < gameState.size && ny >= 0 && ny < gameState.size) {
                    if (gameState.board[ny][nx] === null) {
                        emptyCount++;
                    }
                }
            }
            
            return emptyCount === 0;
        }
        
        // 虚手（跳过回合）
        function pass() {
            if (gameState.gameOver) {
                return;
            }
            
            gameState.passes++;
            
            // 如果连续两次虚手，游戏结束
            if (gameState.passes >= 2) {
                gameState.gameOver = true;
                updateMessage("游戏结束，请数子计算胜负");
            } else {
                gameState.turn = gameState.turn === 'black' ? 'white' : 'black';
                drawBoard();
                updateMessage(gameState.turn === 'black' ? "白方虚手" : "黑方虚手");
                
                // 如果是AI模式，让AI落子
                if (gameState.mode === 'ai' && gameState.turn === 'white' && !gameState.gameOver) {
                    setTimeout(aiMove, 500);
                }
            }
        }
        
        // 认输
        function resign() {
            if (gameState.gameOver) {
                return;
            }
            
            gameState.gameOver = true;
            updateMessage(`${gameState.turn === 'black' ? '黑方' : '白方'}认输，${gameState.turn === 'black' ? '白方' : '黑方'}获胜`);
        }
        
        // AI落子
        function aiMove() {
            // 简单AI策略：随机找一个合法的位置落子
            // 在真实应用中，这里应该使用更复杂的算法
            const validMoves = [];
            
            for (let y = 0; y < gameState.size; y++) {
                for (let x = 0; x < gameState.size; x++) {
                    if (gameState.board[y][x] === null) {
                        // 检查是否是打劫点
                        if (gameState.koPoint && gameState.koPoint.x === x && gameState.koPoint.y === y) {
                            continue;
                        }
                        
                        // 测试落子
                        const testBoard = gameState.board.map(row => [...row]);
                        testBoard[y][x] = 'white';
                        
                        // 检查是否有提子
                        const capturedStones = findCapturedStones(testBoard, 'black');
                        
                        // 检查自杀手
                        if (capturedStones.length === 0) {
                            const selfCaptured = isSelfCaptured(testBoard, x, y, 'white');
                            if (selfCaptured) {
                                continue;
                            }
                        }
                        
                        validMoves.push({x, y});
                    }
                }
            }
            
            // 如果有合法的位置，随机选择一个
            if (validMoves.length > 0) {
                const randomMove = validMoves[Math.floor(Math.random() * validMoves.length)];
                placeStone(randomMove.x, randomMove.y);
            } else {
                // 如果没有合法的位置，虚手
                pass();
            }
        }
        
        // 更新提子显示
        function updateCapturedDisplay() {
            document.getElementById('blackCaptured').textContent = `黑方提子: ${gameState.blackCaptured}`;
            document.getElementById('whiteCaptured').textContent = `白方提子: ${gameState.whiteCaptured}`;
        }
        
        // 更新消息
        function updateMessage(text) {
            document.getElementById('message').textContent = text;
        }
        
        // 事件监听
        document.getElementById('restartButton').addEventListener('click', initGame);
        document.getElementById('passButton').addEventListener('click', pass);
        document.getElementById('resignButton').addEventListener('click', resign);
        document.getElementById('gameMode').addEventListener('change', initGame);
        document.getElementById('boardSize').addEventListener('change', initGame);
        
        // 初始化游戏
        initGame();
    </script>
</body>
</html>